home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / Snippets / Interapplication Comm. / SuspendAppleEvent / SuspendEvent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-26  |  25.5 KB  |  658 lines  |  [TEXT/MPS ]

  1. /* SuspendEvent */
  2. /* A simple example of suspending and resuming an AppleEvent */
  3. /* Written by C.K. Haun <TR> */
  4. /* Apple Developer Tech Support */
  5. /* Of course, Copyright 1991-1992, Apple Computer Inc. */
  6.  
  7. #include "SuspendEvent.h"
  8.  
  9. /* prototypes */
  10. void InitalizeApp(void);
  11. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  12. void DrawMain(WindowPtr drawIt);
  13. Boolean DoSelected(long val);
  14. void SizeMain(WindowPtr theWindow);
  15. void InitAEStuff(void);
  16. void DoHighLevel(EventRecord *AERecord);
  17. void DoDaCall(MenuHandle themenu, long theit);
  18. void DoDocumentClick(WindowPtr theWindow);
  19. OSErr modfiedProcessOpenPrint(AppleEvent *messagein, AppleEvent *theReply, Boolean printIt);
  20. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  21. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  22. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  23. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  24. void SampleHelpDialog(void);
  25. WindowPtr AddNewWindow(short theID);
  26. void InvalAll(void);
  27. void NilProc(void);
  28. /* one external */
  29. extern void _DataInit();                                    /* this is the C initialization code */
  30.  
  31. /* globals */
  32. Boolean gQuit, gInBackground;
  33. unsigned long gMySleep;
  34. ProcessSerialNumber gOurSN;
  35. short gHelpItem;
  36.  
  37. /* globals for event suspension */
  38. Boolean eventIsPending;
  39. AEDesc theSuspEvent, theSuspReply;
  40.  
  41. #pragma segment Main
  42. main()
  43. {
  44.     EventRecord myEventRecord;
  45.     WindowPtr twindow;
  46.     short fHit;
  47.     windowCHandle tempWCH;
  48.     
  49.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  50.     InitalizeApp();
  51.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  52.     do {
  53.         
  54.         WaitNextEvent(everyEvent, &myEventRecord, gMySleep, nil);
  55.         switch (myEventRecord.what) {
  56.             case nullEvent:
  57.                 /* no nul processing in this sample */
  58.                 break;
  59.             case updateEvt:
  60.                 /* always check to see if it's my window */
  61.                 /* this may not seem necessary under 7.0, where it's unlikely or impossible for */
  62.                 /* a DA to be in your layer, but there are others */
  63.                 /* who can stick themselves into your window list, */
  64.                 /* BalloonWriter comes quickly to mind */
  65.                 if (((WindowPeek)myEventRecord.message)->windowKind == kMyDocumentWindow) {
  66.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  67.                     if (tempWCH)
  68.                         (ProcPtr)((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  69.                 }
  70.                 break;
  71.             case mouseDown:
  72.                 /* first see where the hit was */
  73.                 fHit = FindWindow(myEventRecord.where, &twindow);
  74.                 switch (fHit) {
  75.                     Rect limitRect;
  76.                     Str255 tempString;
  77.                     long back;
  78.                     case inDesk:                            /* if they hit in desk, then the process manager */
  79.                         break;                              /* will switch us out, we don't need to do anything */
  80.                     case inMenuBar:
  81.                         DoSelected(MenuSelect(myEventRecord.where));
  82.                         break;
  83.                         
  84.                     case inSysWindow:
  85.                         /* pass to the system */
  86.                         SystemClick(&myEventRecord, twindow);
  87.                         break;
  88.                     case inContent:
  89.                         /* Handle content and control clicks here */
  90.                         if (FrontWindow()) {                /* don't do this unless we have a window open, silly */
  91.                             if (FrontWindow() == twindow && (((WindowPeek)twindow)->windowKind == kMyDocumentWindow)) {
  92.                                 windowCHandle clicker;
  93.                                 clicker = (windowCHandle)GetWRefCon(twindow);
  94.                                 /* jump to the content function stored for this window */
  95.                                 HLock((Handle)clicker);     /* lock it down so things don't get stupid */
  96.                                 (ProcPtr)((*clicker)->clickMe)(twindow);
  97.                                 HUnlock((Handle)clicker);       /* all done */
  98.                             } else {
  99.                                 SelectWindow(twindow);      /* select the window */
  100.                                 SetPort(twindow);
  101.                             }
  102.                         }
  103.                         break;
  104.                     case inDrag:
  105.                         DragWindow(twindow, myEventRecord.where, &qd.screenBits.bounds);
  106.                         break;
  107.                     case inGrow:
  108.                         /* Call GrowWindow here if you have a grow box */
  109.                         SetPort(twindow);
  110.                         limitRect = qd.screenBits.bounds;
  111.                         limitRect.top = kMinHeight;
  112.                         GetWTitle(twindow, tempString);
  113.                         /* I'm not letting the user shrink the window so */
  114.                         /* small that the title is truncated */
  115.                         limitRect.left = StringWidth(tempString) + 120;
  116.                         back = GrowWindow(twindow, myEventRecord.where, &limitRect);
  117.                         
  118.                         if (back) {
  119.                             windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  120.                             Rect sizeRect = ((WindowPtr)twindow)->portRect;
  121.                             InvalRect(&sizeRect);
  122.                             sizeRect.top = sizeRect.bottom - 16;
  123.                             sizeRect.left = sizeRect.right - 16;
  124.                             EraseRect(&sizeRect);
  125.                             InvalRect(&sizeRect);
  126.                             SizeWindow(twindow, back & 0xffff, back >> 16, true);
  127.                             (ProcPtr)((*tempWCH)->sizeMe)(twindow);
  128.                         }
  129.                         InvalRect(&twindow->portRect);
  130.                         
  131.                         break;
  132.                     case inGoAway:
  133.                         /* Click in Close box */
  134.                         if (TrackGoAway(twindow, myEventRecord.where))
  135.                             (ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
  136.                         
  137.                         break;
  138.                     case inZoomIn:
  139.                     case inZoomOut:
  140.                         if (TrackBox(twindow, myEventRecord.where, fHit)) {
  141.                             windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  142.                             SetPort(twindow);
  143.                             
  144.                             ZoomWindow(twindow, fHit, true);
  145.                             InvalRect(&twindow->portRect);
  146.                             (ProcPtr)((*tempWCH)->sizeMe)(twindow);
  147.                         }
  148.                 }
  149.             case mouseUp:
  150.                 /* don't care */
  151.                 break;
  152.                 /* same action for key or auto key */
  153.             case keyDown:
  154.             case autoKey:
  155.                 if (myEventRecord.modifiers & cmdKey)
  156.                     DoSelected(MenuKey(myEventRecord.message & charCodeMask));
  157.                 break;
  158.             case keyUp:
  159.                 /* don't care */
  160.                 break;
  161.             case diskEvt:
  162.                 /* I don't do anything special for disk events, this just passes them */
  163.                 /* to a function that checks for an error on the mount */
  164.                 DoDiskEvents(myEventRecord.message);
  165.                 break;
  166.             case activateEvt:
  167.                 if (myEventRecord.modifiers & activeFlag) {
  168.                     tempWCH = (windowCHandle)GetWRefCon((WindowPtr)myEventRecord.message);
  169.                     (ProcPtr)((*tempWCH)->drawMe)((WindowPtr)myEventRecord.message);
  170.                 }
  171.                 break;
  172.             case networkEvt:
  173.                 /* don't care */
  174.                 break;
  175.             case driverEvt:
  176.                 /* don't care */
  177.                 break;
  178.             case app4Evt:
  179.                 switch ((myEventRecord.message >> 24) & 0x0FF) {        /* high byte of message */
  180.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  181.                         gInBackground = (myEventRecord.message & kResumeMask) == 0;
  182.                         if (gInBackground) {
  183.                             /* nothing for going in the background in this sample */
  184.                         } else {
  185.                             /* make sure the cursor is an arrow when we come forward */
  186.                             InitCursor();
  187.                         }
  188.                         break;
  189.                 }
  190.                 break;
  191.             default:
  192.                 break;
  193.                 /* This dispatches high level events (AppleEvents, for example) */
  194.                 /* to our dispatch routine. This is NEW in the event loop for */
  195.                 /* System 7 */
  196.             case kHighLevelEvent:
  197.                 DoHighLevel(&myEventRecord);
  198.                 break;
  199.                 
  200.         }
  201.     }
  202.             while (gQuit != true);
  203.     
  204. }
  205.  
  206. /* DoDaCall opens the requested DA. It's here as a seperate routine if you'd */
  207. /* like to perform some action or just know when a DA is opened in your */
  208. /* layer. Can be handy to track memory problems when a DA is opened */
  209. /* with an Option-open */
  210. void DoDaCall(MenuHandle themenu, long theit)
  211. {
  212.     long qq;
  213.     char DAname[255];
  214.     GetItem(themenu, theit, &DAname);
  215.     qq = OpenDeskAcc(DAname);
  216. }
  217.  
  218. /* end DoDaCall */
  219.  
  220. /* DoDiskEvents just checks the error code from the disk mount, */
  221. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  222. /* You can do much more here if you care about what disks are */
  223. /* in the drive */
  224. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  225. {
  226.     short hival, loval, tommy;
  227.     Point fredpoint =  {
  228.         40, 40
  229.     };
  230.     hival = HiWord(dinfo);
  231.     loval = LoWord(dinfo);
  232.     if (hival != noErr)                                     /* something happened */ {
  233.         tommy = DIBadMount(fredpoint, dinfo);
  234.     }
  235. }
  236.  
  237. /* draws my window. Pretty simple */
  238. void DrawMain(WindowPtr drawIt)
  239. {
  240.     RgnHandle tempRgn;
  241.     short oldSize = drawIt->txSize;
  242.     Rect scratchRect;
  243.     BeginUpdate(drawIt);
  244.     SetPort(drawIt);
  245.     EraseRect(&drawIt->portRect);
  246.     /* tell folks if an event has been suspendered */
  247.     if (eventIsPending) {
  248.         Str255 tempString;
  249.         MoveTo(10, 40);
  250.         TextFace(bold);
  251.         TextSize(24);
  252.         
  253.         GetIndString(tempString, kGeneralStrings, kPendingWords1);
  254.         DrawString(tempString);
  255.         GetIndString(tempString, kGeneralStrings, kPendingWords2);
  256.         MoveTo(10, 80);
  257.         DrawString(tempString);
  258.         
  259.         TextSize(oldSize);
  260.         TextFace(normal);
  261.     }
  262.     scratchRect = drawIt->portRect;
  263.     scratchRect.top = scratchRect.bottom - 15;
  264.     scratchRect.left = scratchRect.right - 15;
  265.     tempRgn = NewRgn();
  266.     GetClip(tempRgn);
  267.     ClipRect(&scratchRect);
  268.     DrawGrowIcon(drawIt);
  269.     SetClip(tempRgn);
  270.     DisposeRgn(tempRgn);
  271.     
  272.     EndUpdate(drawIt);
  273. }
  274.  
  275. void CloseMyWindow(WindowPtr twindow)
  276. {
  277.     DisposeWindow(twindow);
  278. }
  279.  
  280. /* my menu action taker. It returns a Boolean which I usually ignore, but it */
  281. /* mught be handy someday */
  282. /* Actually, I've been returning that Boolean for 7 years, and */
  283. /* never used it, but Who Knows? */
  284. /* I usually use it in an application to determine if a keystroke was accepted */
  285. /* by a menu or whether it should be passed along to any other key acceptors */
  286. Boolean DoSelected(long val)
  287. {
  288.     short loval, hival;
  289.     Boolean returnVal = false;
  290.     loval = LoWord(val);
  291.     hival = HiWord(val);
  292.     
  293.     switch (hival) {                                        /* switch off the menu number selected */
  294.         case kAppleMenu:                                    /* Apple menu */
  295.             if (loval != 1) {                               /* if this was not About, it's a DA */
  296.                 DoDaCall(GetMHandle(kAppleMenu), loval);
  297.             } else {
  298.                 Alert(kAboutBox, nil);                      /* do about box */
  299.             }
  300.             returnVal = true;
  301.             break;
  302.         case kFileMenu:                                     /* File menu */
  303.             switch (loval) {
  304.                 case kQuitItem:
  305.                     gQuit = true;                           /* only item */
  306.                     returnVal = true;
  307.                     break;
  308.                 default:
  309.                     break;
  310.             }
  311.             break;
  312.         case kEditMenu:
  313.             /* edit menu junk */
  314.             /* don't care */
  315.             switch (loval) {
  316.             default:
  317.                 break;
  318.             }
  319.             break;
  320.         case kToolsMenu:
  321.             /* add all your test stuff here */
  322.             switch (loval) {
  323.             default:
  324.                 break;
  325.             }
  326.             break;
  327.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  328.             /* I only care about this item. If anything else is returned here, I don't know what */
  329.             /* it is, so I leave it alone. Remember, the Help Manager chapter says that */
  330.             /* Apple reserves the right to add and change things in the Help menu */
  331.             
  332.             if (loval == gHelpItem)
  333.                 SampleHelpDialog();
  334.             break;
  335.             
  336.     }
  337.     HiliteMenu(0);
  338.     return(returnVal);
  339. }
  340.  
  341. void DoDocumentClick(WindowPtr theWindow)
  342. {
  343.     /* look to see if an event is pending, if so resume the event */
  344.     if (eventIsPending) {
  345.         /* restart the event */
  346.         AEResumeTheCurrentEvent(&theSuspEvent, &theSuspReply, (ProcPtr)kAEUseStandardDispatch, 0);
  347.         /* kAEUseStandardDispatch means re-enter the handler from the top. */
  348.         /* You're other option to pass here is kAENoDispatch, which tells the */
  349.         /* AppleEvent manager that this event is FINISHED, clean up memory */
  350.         /* and don't re-dspatch. */
  351.         
  352.     }
  353. }
  354.  
  355.  
  356. #pragma segment Initialize
  357.  
  358. /* InitAEStuff installs my appleevent handlers */
  359. void InitAEStuff(void)
  360. {
  361.     AEinstalls HandlersToInstall[] =  {
  362.         {
  363.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  364.         },  {
  365.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  366.         },  {
  367.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  368.         },  {
  369.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  370.         }, 
  371.         /* The above are the four required AppleEvents. */
  372.         
  373.     };
  374.     
  375.     OSErr aevtErr = noErr;
  376.     long aLong = 0;
  377.     Boolean gHasAppleEvents = false;
  378.     /* Check this machine for AppleEvents. If they are not here (ie not 7.0)
  379.     * then we exit */
  380.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  381.     /* The following series of calls installs all our AppleEvent Handlers.
  382.     * These handlers are added to the application event handler list that 
  383.     * the AppleEvent manager maintains. So, whenever an AppleEvent happens
  384.     * and we call AEProcessEvent, the AppleEvent manager will check our
  385.     * list of handlers and dispatch to it if there is one.
  386.     */
  387.     if (gHasAppleEvents) {
  388.         register qq;
  389.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  390.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  391.                                             HandlersToInstall[qq].theProc, 0, false);
  392.             if (aevtErr) {
  393.                 ExitToShell();                              /* just fail, baby */
  394.             }
  395.         }
  396.     } else {
  397.         ExitToShell();
  398.     }
  399. }
  400.  
  401. /* end InitAEStuff */
  402.  
  403. #pragma segment Main
  404.  
  405. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  406. /* easy for me to say, huh? */
  407. void DoHighLevel(EventRecord *AERecord)
  408. {
  409.     OSErr myErr;
  410.     myErr = AEProcessAppleEvent(AERecord);
  411.     
  412. }
  413.  
  414. /* end DoHighLevel */
  415.  
  416. /* This is the standard Open Application event. */
  417. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  418. {
  419.     WindowPtr myWindow;
  420.  
  421. #pragma unused (messagein,reply,refIn)
  422.     /* we of course don't do anything here in this simple app */
  423.     /* except open our window */
  424.     myWindow = AddNewWindow(kDocWindowResID);
  425.     
  426.     return(noErr);
  427. }
  428.  
  429. /* end AEOpenHandler */
  430.  
  431. /* Open Doc, opens our documents. Remember, this can happen at application start AND */
  432. /* anytime else. If your app is up and running and the user goes to the desktop, hilites one */
  433. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  434. /* handler will get called. Which means you don't do any initialization of globals here, or */
  435. /* anything else except open then doc. */
  436. /* SO-- Do NOT assume that you are at app start time in this */
  437. /* routine, or bad things will surely happen to you. */
  438.  
  439. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  440. {
  441. #pragma unused (refIn)
  442.     return(modfiedProcessOpenPrint(messagein, reply, false));
  443. }
  444.  
  445. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  446. {                                                           /* no printing handler in yet, so we'll ignore this */
  447.     /* the operation is functionally identical to the ODOC event, with the additon */
  448.     /* of calling your print routine. */
  449. #pragma unused (refIn)
  450.     return(modfiedProcessOpenPrint(messagein, reply, true));
  451. }
  452.  
  453. /* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
  454. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
  455. /* OK, it's a few months after I wrote that comment, and I've seen a lot of code */
  456. /* come through DTS that calls ExitToShell from quit handlers. Let me explain... */
  457. /* When an AppleEvent Handler is called (like this quit handler) you are ALMOST */
  458. /* 100% in your application world. A5 is right, you can call any toolbox function, */
  459. /* you can call your own routines, everything _seems_ like you are in complete */
  460. /* control. Well, almost but not quite. The routine has been dispatch to from the */
  461. /* AppleEvent Manager's space, so you _must_ return to that at some point! */
  462. /* Which is why you can't call ETS from here. When you call ExitToShell from an */
  463. /* AE Handler, the most likely thing that happens is the FInder quits, and your */
  464. /* application keeps running. Which ain't what you want, y'know? */
  465. /* so, DON'T CALL EXITTOSHELL FROM AN APPLEEVENT HANDLER!!!!!!!!!!!!!! */
  466. /* Any of 'em, not just a quit handler. Just don't do it. */
  467. /* This comment keeps getting longer because people keep doing it STOP IT! */
  468. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  469. {
  470. #pragma unused (messagein,refIn,reply)
  471.     gQuit = true;
  472.     return(noErr);
  473. }
  474.  
  475. /* This is my sample help dialog. Does not do anything, expand as you need */
  476. void SampleHelpDialog(void)
  477. {
  478.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  479.     short itemhit = 0;
  480.     while (itemhit != 1) {
  481.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  482.     }
  483.     DisposDialog(tdial);
  484. }
  485.  
  486.  
  487. #pragma segment Initialize
  488. void InitalizeApp(void)
  489. {
  490.     Handle myMenu;
  491.     MenuHandle helpHandle;
  492.     StringHandle helpString;
  493.     short count;
  494.     long vers;
  495.     MaxApplZone();
  496.     InitGraf((Ptr)&qd.thePort);
  497.     InitFonts();
  498.     InitWindows();
  499.     InitMenus();
  500.     TEInit();
  501.     InitDialogs(nil);
  502.     InitCursor();
  503.     /* Check system version */
  504.     Gestalt(gestaltSystemVersion, &vers);
  505.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  506.     if (vers < 7) {
  507.         StopAlert(kBadSystem, nil);
  508.         ExitToShell();
  509.     }
  510.     InitAEStuff();
  511.     /* set up my menu junk */
  512.     SetMenuBar(GetNewMBar(kMBarID));
  513.     AddResMenu(GetMHandle(kAppleMenu), 'DRVR');
  514.     
  515.     /* now install my Help menu item in the Help Manager's menu */
  516.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  517.     count = CountMItems(helpHandle);                        /* How many items are there? */
  518.     helpString = GetString(kHelpString);                    /* get my help string */
  519.     DetachResource(helpString);                             /* detach it */
  520.     HNoPurge(helpString);
  521.     MoveHHi((Handle)helpString);
  522.     HLock((Handle)helpString);
  523.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  524.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  525.     
  526.     DrawMenuBar();
  527.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  528.     
  529. }
  530.  
  531.  
  532. #pragma segment Main
  533. WindowPtr AddNewWindow(short theID)
  534. {
  535.     windowCHandle setControls;
  536.     WindowPtr tempWP;
  537.     short cnt = 0;
  538.     Str31 wtitle;
  539.     tempWP = GetNewWindow(theID, 0, (WindowPtr)-1);         /* get a new window */
  540.     ((WindowPeek)tempWP)->windowKind = kMyDocumentWindow;       /* mark it as my document window */
  541.     setControls = (windowCHandle)NewHandleClear(sizeof(windowControl));     /* add our control structure to it */
  542.     SetWRefCon(tempWP, (long)setControls);                  /* stop stuffing refCon directly <ckh 1.0.3> */
  543.     HLock((Handle)setControls);                             /* lock it down while we fill it*/
  544.     
  545.     /* add pointers to our procedures for drawing, saving, and closing */
  546.     /* This way, all I need is one dispatch point for drawing, closing */
  547.     /* or whatever, I don't have to case off the window kind to go to the */
  548.     /* correct routine. Kinda like object-oriented programming, but I won't */
  549.     /* admit that. */
  550.     (*setControls)->drawMe = (ProcPtr)DrawMain;
  551.     (*setControls)->clickMe = (ProcPtr)DoDocumentClick;
  552.     (*setControls)->sizeMe = (ProcPtr)SizeMain;
  553.     (*setControls)->closeMe = (ProcPtr)CloseMyWindow;
  554.     (*setControls)->generalData = NewHandle(0);
  555.     return(tempWP);
  556. }
  557.  
  558. void SizeMain(WindowPtr theWindow)
  559. {
  560.     WindowPtr tempWP;
  561.     GetPort(&tempWP);
  562.     InvalRect(&theWindow->portRect);
  563.     SetPort(tempWP);
  564. }
  565.  
  566. void NilProc(void)
  567. {
  568.     
  569. }
  570.  
  571. /* modfiedProcessOpenPrint handles ODOC and PDOC events. Both events open a document, one prints it */
  572. /* This one is modified to suspend any event that opens or prints an kAlDocType document */
  573. /* do NOT use this as is in your app! */
  574. OSErr modfiedProcessOpenPrint(AppleEvent *messagein, AppleEvent *theReply, Boolean printIt)
  575. {
  576.     OSErr err = noErr;
  577.     AEDesc theDesc;
  578.     FSSpec theFSS;
  579.     short loopy;
  580.     long numFilesToOpen;
  581.     AEKeyword ignoredKeyWord;
  582.     DescType ignoredType;
  583.     Size ignoredSize;
  584.     FInfo fileInfo;
  585.     Boolean DoSuspend = false;
  586.     WindowPtr tWind;
  587.     err = AEGetParamDesc(messagein, keyDirectObject, typeAEList, &theDesc);
  588.     err |= AECountItems(&theDesc, &numFilesToOpen);
  589.     if (!err) {
  590.         for (loopy = 1; ((loopy <= numFilesToOpen) && (!err)); ++loopy) {
  591.             
  592.             err = AEGetNthPtr(&theDesc, loopy, typeFSS, &ignoredKeyWord, &ignoredType, (Ptr)&theFSS, sizeof(theFSS),
  593.                               &ignoredSize);
  594.             if (err == noErr) {
  595.                 FSpGetFInfo(&theFSS, &fileInfo);
  596.                 /* make sure it's a data file */
  597.                 /* and if this was called for an eventPend, don't reopen the kFredDocType docs */
  598.                 if (fileInfo.fdCreator == kSuspCreator && fileInfo.fdType == kFredDocType && !eventIsPending) {
  599.                     WindowPtr newW = AddNewWindow(kDocWindowResID);
  600.                     if (newW) {
  601.                         SetWTitle(newW, &theFSS.name);
  602.                     }
  603.                 } else {
  604.                     /* here we see if it's an kAlDocType file. If it is, we either ignore it */
  605.                     /* if its not from the resume, or we process it */
  606.                     if (fileInfo.fdCreator == kSuspCreator && fileInfo.fdType == kAlDocType) {
  607.                         if (eventIsPending) {
  608.                             WindowPtr newW = AddNewWindow(kDocWindowResID);
  609.                             if (newW) {
  610.                                 SetWTitle(newW, &theFSS.name);
  611.                             }
  612.                         } else {
  613.                             /* if there is not an event pending, then this is is an Al file */
  614.                             /* from launch, tell ourselves that there is a reason to suspend */
  615.                             DoSuspend = true;
  616.                         }
  617.                     }
  618.                 }
  619.             }
  620.         }                                                   /* for loopy = ... */
  621.     }
  622.     AEDisposeDesc(&theDesc);
  623.     /* determine if this is the first pass, then we should suspend. If not, */
  624.     /* we press on */
  625.     if (eventIsPending) {
  626.         /* clear it and life is back to normal */
  627.         eventIsPending = false;
  628.     } else {
  629.         /* first pass, no kAlDocType files have been opened, suspend the event and set the */
  630.         /* flag. */
  631.         /* Only if an kAlDocType file was passed at all, which is the DoSuspend flag. */
  632.         if (DoSuspend) {
  633.             eventIsPending = true;
  634.             AESuspendTheCurrentEvent(messagein);
  635.             theSuspEvent = *messagein;
  636.             theSuspReply = *theReply;
  637.         }
  638.     }
  639.     InvalAll();
  640.     return(err);
  641. }
  642.  
  643. void InvalAll(void)
  644. {
  645.     WindowPtr nowFront = FrontWindow();
  646.     WindowPtr oldPort;
  647.     GetPort(&oldPort);
  648.     while (nowFront) {
  649.         if (((WindowPeek)nowFront)->visible) {
  650.             SetPort(nowFront);
  651.             InvalRect(&nowFront->portRect);
  652.         }
  653.         nowFront = (WindowPtr)((WindowPeek)nowFront)->nextWindow;
  654.     }
  655.     SetPort(oldPort);
  656.     
  657. }
  658.